﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using Pixysoft.Reflection;

namespace Pixysoft.Framework.Verifications
{
    public static class Exceptions
    {
        /// <summary>
        /// 当前异常是否被处理过
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static bool IsHandled(Exception ex)
        {
            ExpectedException expectedException = ex as ExpectedException;

            if (expectedException == null)
                return false;

            return expectedException.IsHandled;
        }

        /// <summary>
        /// 处理未知异常 一般是bug
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static ExpectedException Parse(Exception ex)
        {
            ExpectedException expectedException = ex as ExpectedException;

            if (expectedException == null)
                return new UnexpectedException(ex.Message, ex);

            return expectedException;
        }

        /// <summary>
        /// 输入错误异常
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static VerificationFailedException VerificationFailedException(params object[] parameters)
        {
            //获取入口参数

            StackTrace stack = new StackTrace(true);

            StackFrame frame = stack.GetFrame(1);

            MethodBase method = frame.GetMethod();

            StringBuilder builder = new StringBuilder();

            if (method == null)
            {
                builder.AppendLine("UNKNOWN METHOD input(s) invalid.");
            }
            else
            {
                builder.AppendLine(string.Format("[{0}] input(s) invalid.", method.Name));

                Type declareType = method.DeclaringType;

                if (declareType != null)
                {
                    string assemblyname = Pixysoft.Tools.AssemblyHelper.Instance.GetAssemblyName(method.DeclaringType.Assembly);

                    string typename = Pixysoft.Reflection.ReflectHelper.Instance.RegularTypeName(declareType);

                    builder.Append(string.Format("{0}::{1}.{2}", assemblyname, typename, method.Name))
                        .Append("(");

                    bool founded = false;
                    foreach (ParameterInfo paremeter in method.GetParameters())
                    {
                        builder.Append(string.Format("{0} {1},", paremeter.ParameterType.Name, paremeter.Name));
                        founded = true;
                    }
                    if (founded)
                        builder.Remove(builder.Length - 1, 1);

                    builder.AppendLine(")");
                }
            }

            int counter = 0;

            foreach (ParameterInfo paremeter in method.GetParameters())
            {
                object parameterValue = null;

                if (counter < parameters.Length)
                    parameterValue = parameters[counter];

                if (parameterValue == null)
                    builder.AppendLine(string.Format("::{0} {1} = null;", paremeter.ParameterType.Name, paremeter.Name));
                else
                    builder.AppendLine(string.Format("::{0} {1} = {2};", paremeter.ParameterType.Name, paremeter.Name, parameterValue));

                counter++;
            }

            return new VerificationFailedException(builder.ToString());

        }

        /// <summary>
        /// 输入错误异常
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static VerificationFailedException ManualVerificationFailedException(string message, params object[] parameters)
        {
            string messagetext = message;

            if (parameters == null || parameters.Length == 0)
                messagetext = message;
            else
                messagetext = string.Format(message, parameters);

            return new VerificationFailedException(messagetext);

        }

        /// <summary>
        /// 外部异常
        /// </summary>
        /// <param name="exception"></param>
        /// <returns></returns>
        public static ExternalException ExternalException(Exception exception)
        {
            return new ExternalException(exception.Message, exception);
        }

        /// <summary>
        /// 外部异常
        /// </summary>
        /// <param name="message"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static ExternalException ExternalException(string message, params object[] parameters)
        {
            string exceptionMessage = null;

            if (parameters == null || parameters.Length == 0)
                exceptionMessage = message;
            else
                exceptionMessage = string.Format(message, parameters);

            return new ExternalException(exceptionMessage);
        }

        /// <summary>
        /// 外部异常
        /// </summary>
        /// <param name="exception"></param>
        /// <param name="message"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static ExternalException ExternalException(Exception exception, string message, params object[] parameters)
        {
            string exceptionMessage = null;

            if (parameters == null || parameters.Length == 0)
                exceptionMessage = message;
            else
                exceptionMessage = string.Format(message, parameters);

            return new ExternalException(exceptionMessage, exception);
        }

        /// <summary>
        /// 结果不存在异常
        /// </summary>
        /// <param name="message"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static UnexpectedResultException UnexpectedResultException(string message, params object[] parameters)
        {
            //TODO 获取返回的源信息 

            string exceptionMessage = null;

            if (parameters == null || parameters.Length == 0)
                exceptionMessage = message;
            else
                exceptionMessage = string.Format(message, parameters);

            return new UnexpectedResultException(exceptionMessage);
        }


        public static void Throw(ExpectedException ex)
        {
            //将来这里可以扩展出抛出策略

            throw ex;
        }

    }
}
